package edu.gyc.mysystem.shiro;

import edu.gyc.mysystem.dao.PermissionMapper;
import edu.gyc.mysystem.dao.RoleMapper;
import edu.gyc.mysystem.dao.UserMapper;
import edu.gyc.mysystem.model.Permission;
import edu.gyc.mysystem.model.Role;
import edu.gyc.mysystem.model.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;

public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    RoleMapper roleMapper;
    @Autowired
    PermissionMapper permissionMapper;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user=(User) SecurityUtils.getSubject().getPrincipal();
        Set<Role> roles = roleMapper.findRolesByUserId(user.getUid());
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        for (Role role :
                roles) {
            authorizationInfo.addRole(role.getRole());
        }
        if (roles.size() > 0) {  //用户有可能没有分配角色，比如刚注册成功。
            Set<Permission> permissions = permissionMapper.findPermissionsByRoleId(roles);
            for (Permission p : permissions) {
                authorizationInfo.addStringPermission(p.getPermission());
            }
        }
        return authorizationInfo;
    }
@Autowired
    UserMapper userMapper;
    /**
     * 验证用户身份
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取用户通过表单提交的用户名和密码 第一种方式
        //String username = (String) authenticationToken.getPrincipal();
        //String password = new String((char[]) authenticationToken.getCredentials());

        //获取用户名 密码 第二种方式
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
        String username = usernamePasswordToken.getUsername();
        String password = new String(usernamePasswordToken.getPassword());
        //从数据库查询用户信息
        User user = userMapper.selectByUsername(username);
        //可以在这里直接对用户名校验,或者调用 CredentialsMatcher 校验
        if (user == null) {
            throw new UnknownAccountException("用户名错误！");
        }

        //密码明文比对因加密被取消
//        if (!password.equals(user.getPassword())) {
//            throw new IncorrectCredentialsException("密码错误！");
//        }
        if ("1".equals(user.getState())) {
            throw new LockedAccountException("账号已被锁定,请联系管理员！");
        }

//        非加密
//        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(), getName());
//        加密
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                user,
                user.getPassword(),
                ByteSource.Util.bytes(user.getSalt()),
                getName());
        return info;

    }

    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher hashedCredentialsMatcher=new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("SHA-256");
        hashedCredentialsMatcher.setHashIterations(911);
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(false);
        super.setCredentialsMatcher(hashedCredentialsMatcher);
    }
}
